package com.unicom.office.impl;

import com.unicom.office.builder.ExcelBuilder;
import com.unicom.office.config.OfficeConfig;
import com.unicom.office.runtime.OfficeRuntime;
import com.unicom.office.unit.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFHyperlink;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;

import java.io.FileOutputStream;
import java.util.List;

public class XlsxEasyBuilder extends ExcelBuilder {
    public XlsxEasyBuilder(){
        super(null, null);
    }

    public XlsxEasyBuilder(OfficeConfig config, OfficeRuntime runtime) {
        super(config, runtime);
    }

    protected Object buildWorkbook(WorkbookUnit unit) {
        for (OfficeUnit child : unit.getChildren()) {
            build2(child, unit.getSource());
        }
        return unit.getSource();
    }

    protected Object buildWorksheet(WorksheetUnit unit, Object parent) {
        for (OfficeUnit child : unit.getChildren()) {
            build2(child, unit.getSource());
        }
        return unit.getSource();
    }

    protected Object buildRow(RowUnit unit, Object parent) {
        for (OfficeUnit child : unit.getChildren()) {
            build2(child, unit.getSource());
        }
        return unit.getSource();
    }

    protected Object buildCell(CellUnit unit, Object parent) {
        Cell cell = (Cell) unit.getSource();
        if(!unit.isJustResource()) {
            setCellValue(cell, unit);
        }
        return cell;
    }

    public void setCellValue(Cell cell, CellUnit unit) {
        if (cell != null) {
            CellType copyCellType = cell.getCellType();
            if (copyCellType == CellType.FORMULA) {
                copyCellType = cell.getCachedFormulaResultType();
            }

            switch(copyCellType) {
                case NUMERIC:
                    cell.setCellValue(Double.parseDouble(unit.getText()));
                    if (DateUtil.isCellDateFormatted(cell)) {
                        cell.setCellValue(cell.getDateCellValue());
                    } else {
                        cell.setCellValue(cell.getNumericCellValue());
                    }
                    break;
                case STRING:
                    // 设置文本
                    for (OfficeUnit paragraph : unit.getChildren()) {
                        cell.setCellValue(buildRichText((ParagraphUnit) paragraph));
                    }
                    break;
                case FORMULA:
                    //cell.setCellFormula(cell.getCellFormula());
                    break;
                case BLANK:
                    //cell.setBlank();
                    break;
                case BOOLEAN:
                    //cell.setCellValue(cell.getBooleanCellValue());
                    break;
                case ERROR:
                    //cell.setCellErrorValue(cell.getErrorCellValue());
                    break;
                default:
                    throw new IllegalArgumentException("Invalid cell type " + cell.getCellType());
            }
        } else {
            cell.setBlank();
        }
    }

    private RichTextString buildRichText(ParagraphUnit paragraphUnit) {
        XSSFRichTextString richTextString = new XSSFRichTextString();
        String str = "";
        for (OfficeUnit child : paragraphUnit.getChildren()) {
            if(child.getSource() != null) {
                richTextString.append(str);
                str = "";
                richTextString.append(child.toString(), (XSSFFont)child.getSource());
            }else {
                str += child.toString();
            }
        }
        if(str.length() > 0) {
            richTextString.append(str);
        }

        return richTextString;
    }

    protected Object buildParagraph(ParagraphUnit unit, Object parent) {
        return null;
    }

    protected Object buildTextbox(TextboxUnit unit, Object parent) {
        return null;
    }

    protected Object buildTextrange(TextRangeUnit unit, Object parent) {
        return null;
    }

    protected Object buildPicture(PictureUnit unit, Object parent) {
        return null;
    }

    public void writeFile(Object result, String targetPath) {
        if(!(result instanceof Workbook)) {
            throw new RuntimeException("不能输出文件");
        }

        Workbook wb = (Workbook)result;
        try {
            FileOutputStream file = new FileOutputStream(targetPath);
            wb.write(file);
            file.close();
        }catch(Exception ex){
            throw new RuntimeException(ex.getMessage());
        }
    }
}
